import {_decorator, Component, Node, UITransform, Vec3, tween, find, clamp} from 'cc';
import {PriorityEnum} from "db://assets/scripts/game/PriorityEnum";
import {GameManager} from "db://assets/scripts/game/GameManager";
import {PoolManager} from "db://assets/scripts/common/PoolManager";
import {MonsterController} from "db://assets/scripts/game/role/monster/MonsterController";

const {ccclass, property} = _decorator;

/**
 * 怪物血条控制器
 */
@ccclass('MonsterBloodBarController')
export class MonsterBloodBarController extends Component {
    /**
     * 白色进度条的UI组件
     */
    @property(UITransform)
    public whiteBarTF: UITransform;
    /**
     * 血量进度条的UI组件
     */
    @property(UITransform)
    public redBarTF: UITransform;
    /**
     * 血量容器的UI组件
     */
    @property(UITransform)
    public bloodBarTF: UITransform;

    /**
     * 白色进度条高度
     */
    private whiteBarHeight: number = 19;
    /**
     * 血量进度条高度
     */
    private redBarHeight: number = 19;
    /**
     * 总的血量
     */
    private totalBlood: number = 0;
    /**
     * 当前血量值
     */
    private currentBlood: number = 0;
    /**
     * 血条所在节点绑定的脚本
     */
    private scriptParent: MonsterController;
    /**
     * 当前小怪血条中白色进度条长度
     */
    private maxWhiteBarWidth: number = 104;
    /**
     * 当前小怪血条中血量条长度
     */
    private maxRedBarWidth: number = 104;
    /**
     * 跟随目标
     */
    private targetNode: Node;
    /**
     * 偏差
     */
    private offsetPosition: Vec3;
    /**
     * 当前血条位置
     */
    private currentPosition: Vec3 = new Vec3();
    /**
     * 血条是否为空
     */
    private isBloodEmpty: boolean = false;
    /**
     * 血量为空前的血条位置
     */
    private prevBloodPosition: Vec3 = new Vec3();

    start() {

    }

    update(deltaTime: number) {
        if (this.node.parent && this.node.active && this.targetNode && this.targetNode.parent) {
            let worPos = this.targetNode.worldPosition;

            GameManager.getInstance().mainCamera.convertToUINode(worPos, find("Canvas"), this.currentPosition);
            this.currentPosition.add(this.offsetPosition);
            this.node.setPosition(this.currentPosition);
        }
    }

    /**
     * 显示血条
     *
     * @param scriptParent 脚本所属节点
     * @param totalBlood 总血量
     * @param offsetPosition 血条偏移量
     * @param scale 缩放比
     * @param isInit 是否初始化血条，也就是出生时直接满血
     * @param callback 回调
     */
    public show(scriptParent: MonsterController,
                totalBlood: number,
                offsetPosition: Vec3,
                scale: Vec3,
                isInit: boolean = true,
                callback?: Function) {
        this.scriptParent = scriptParent;
        this.totalBlood = totalBlood * GameManager.getInstance().chapter.hpAddition;
        this.offsetPosition = offsetPosition;
        this.targetNode = scriptParent.node;
        this.isBloodEmpty = false;

        this.prevBloodPosition.set(this.targetNode.worldPosition);

        if (isInit) {
            this.currentBlood = this.totalBlood;
        }

        //当前血量占全部的比例
        let ratio = this.currentBlood / this.totalBlood;
        ratio = clamp(ratio, 0, 1);

        //进度条宽度设置
        this.whiteBarTF.setContentSize(ratio * this.maxWhiteBarWidth, this.whiteBarHeight);
        this.redBarTF.setContentSize(ratio * this.maxRedBarWidth, this.redBarHeight);

        // 设置界面优先级
        this.node.setSiblingIndex(PriorityEnum.BLOOD);

        callback && callback();
    }

    /**
     * 刷新血量
     *
     * @param blood 血量
     */
    public refreshBlood(blood: number) {
        this.currentBlood += blood;

        let ratio = this.currentBlood / this.totalBlood;

        if (blood < 0) {//减血
            ratio = ratio <= 0 ? 0 : ratio;

            this.redBarTF.setContentSize(this.maxRedBarWidth * ratio, this.redBarHeight);

            if (!this.isBloodEmpty) {
                this.isBloodEmpty = ratio <= 0;

                tween(this.whiteBarTF)
                    .to(0.7, {width: this.maxWhiteBarWidth * ratio})
                    .call(() => {
                        if (this.isBloodEmpty) {
                            PoolManager.getInstance().putNode(this.node);
                        }
                    })
                    .start();

                if (this.isBloodEmpty) {
                    this.scriptParent.setIsDie(true);
                }
            } else {
                PoolManager.getInstance().putNode(this.node);
                this.scriptParent.setIsDie(true);
            }
        }
    }
}